package edu.vt.sdm.tcga.filenavigator.parser.expression.level2;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import edu.vt.sdm.tcga.filenavigator.parser.HibernateUtil;

public class LowessNormalizedTable {

	private List<LowessNormalized> values;

	// Accessor methods
	public List<LowessNormalized> getValues() {
		return values;
	}
	public void setValues(List<LowessNormalized> values) {
		this.values = values;
	}
	

	public LowessNormalizedTable(){
		values = new ArrayList<LowessNormalized>();
	}

	public LowessNormalizedTable(String filename){
		this();
		this.loadFromFile(filename);
	}

	
	// Utility functions
	public void loadFromFile(String filename){
		
		// Get current time
		long start = System.currentTimeMillis();
		
		System.out.println("Attempting to load expression genes Lowess normalized file: " + filename);
		
		try {
			BufferedReader in  = new BufferedReader(new FileReader(filename));
			String line = "";
			String delims = "\t";
	
			// Load Analyses
			// Get the header values in the file.
			List<String> headerValues = new ArrayList<String>();
			line = in.readLine();
			String[] tokens = line.split(delims);

			for(int i=0; i<tokens.length; i++){
				headerValues.add(tokens[i]);
			}
			
			List<String> normalizationValues = new ArrayList<String>();
			line = in.readLine();
			tokens = line.split(delims);

			for(int i=0; i<tokens.length; i++){
				normalizationValues.add(tokens[i]);
			}
			
			while( (line = in.readLine()) != null){
				tokens = line.split(delims);

				String gene = tokens[0];

				for(int i=1; i<headerValues.size(); i++){
					String barcode = headerValues.get(i);
					
					// Break barcode up into sub fields here
					// TCGA-A6-2670-01A-02R-0821-07
					// TCGA-A6	Study Number
					// 2670		Patient number
					// 01A		sample ID + suffix
					// 02R		2d vial + suffix
					// 0821-07	DNA Analyte
					String[] barcodeTokens = barcode.split("-");
					String studyNumber = barcodeTokens[0] + "-" + barcodeTokens[1];
					int patientNumber = 0;
					try{
						patientNumber = Integer.parseInt(barcodeTokens[2]);
					}
					catch(NumberFormatException ne){
						System.out.println("Could not format patient number. Value read in as " + 
								barcodeTokens[2] +
								". Setting to 0.");
					}
					
					int sampleID = 0;
					try{
						sampleID = Integer.parseInt(barcodeTokens[3].substring(0, 2));
					}
					catch(NumberFormatException ne){
						System.out.println("Could not format sample ID. Value read in as " + 
								barcodeTokens[2] +
								". Setting to 0.");
					}
					
					String sampleID_suffix = barcodeTokens[3].substring(2, 3);
					int secondVial = 0;
					try{
						sampleID = Integer.parseInt(barcodeTokens[4].substring(0, 2));
					}
					catch(NumberFormatException ne){
						System.out.println("Could not format second vial number. Value read in as " + 
								barcodeTokens[2] +
								". Setting to 0.");
					}
					
					String secondVial_suffix = barcodeTokens[4].substring(2, 3);
					String dnaAnalyte = barcodeTokens[5] + "-" + barcodeTokens[6];
						
					String normalization = normalizationValues.get(i);
					double value = 0.0;
	
					// Error checking
					try{
						value = Double.parseDouble(tokens[i]);
					}
					catch(NumberFormatException ne){
						System.out.println("Could not format value. Value read in as " + 
								tokens[i] +
								". Setting to 0.0.");
					}

//					LowessNormalized lowess = new LowessNormalized(gene, 
//							barcode, 
//							normalization, 
//							value);
					LowessNormalized lowess = new LowessNormalized(barcode, 
							studyNumber,
							patientNumber, 
							sampleID, 
							sampleID_suffix,
							secondVial, 
							secondVial_suffix, 
							dnaAnalyte,
							normalization, 
							gene, 
							value);
					
					values.add(lowess);
				}
			}
			
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		
		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis()-start;
		double seconds = elapsedTimeMillis / 1000.0;
		
		System.out.println("Loaded expression genes Lowess normalized data in " + seconds + " seconds");
	}

	// Save the class out to the database
	public void saveToDatabase(){
		
		// Get current time
		long start = System.currentTimeMillis();
				
		try{
			Session session = HibernateUtil.getSession();
	        Transaction tx = session.beginTransaction();
	        int i = 0;
// 	        int size = this.getValues().size();
	        
	        for(LowessNormalized ln : this.getValues()){
	        	session.save(ln);
		        
	            if ( i % 20 == 0 ) { //Same as the JDBC batch size
	                //flush a batch of inserts and release memory:
	                session.flush();
	                session.clear();
	            }
		        i++;
	        }
	        
	        tx.commit();
	        session.close();
		}
		catch(Exception e){
			e.printStackTrace();
		}

		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis()-start;
		double seconds = elapsedTimeMillis / 1000.0;
		
		System.out.println("Saved expression genes Lowess normalized data in " + seconds + " seconds");
	}

}
